package com.liuym.student.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.liuym.common.constants.Constants;
import com.liuym.common.constants.RedisConstants;
import com.liuym.common.constants.ResponseCodeConstants;
import com.liuym.common.dubbo.student.dto.StudentDTO;
import com.liuym.common.dubbo.table.api.TableNameDubboService;
import com.liuym.common.exception.StudentException;
import com.liuym.student.common.LogAndExceptionCommon;
import com.liuym.student.repository.mapper.StudentMapper;
import com.liuym.student.repository.model.bo.StudentBO;
import com.liuym.student.repository.model.bo.StudentScoreBO;
import com.liuym.student.repository.model.bo.StudentScoreBatchBO;
import com.liuym.student.repository.model.entity.Student;
import com.liuym.student.service.StudentScoreService;
import com.liuym.student.service.StudentService;
import com.vip.vjtools.vjkit.mapper.BeanMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author LiuYiMing
 * @date 2018/9/18 11:43
 * @describe：
 */
@Service
public class StuedntServiceImpl implements StudentService {
    @Autowired
    private StudentMapper studentMapper;

    @Autowired
    private StudentScoreService studentScoreService;

    @Reference(version = "0.0.1")
    private TableNameDubboService tableNameDubboService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Override
    public StudentBO getStudentByNumber(long studentNumber) throws StudentException {
        Student student = studentMapper.getStudentByNumber(studentNumber);
        if (student != null) {
            StudentBO studentBO = BeanMapper.map(student, StudentBO.class);
            return studentBO;
        }
        return null;
    }

    @Override
    public List<StudentBO> getAllStudent() throws StudentException {
        List<Student> studentList = studentMapper.getAllStudent();
        if (studentList != null && studentList.size() > 0) {
            // jdk1.8实现list类型转换
            List<StudentBO> studentBOList =
                    studentList
                            .stream()
                            .map(s -> BeanMapper.map(s, StudentBO.class))
                            .collect(Collectors.toList());
            return studentBOList;
        }
        return null;
    }

    @Override
    public List<StudentBO> getStudentByClass(long classNumber) throws StudentException {
        List<Student> studentList = studentMapper.getStudentByClass(classNumber);
        if (studentList != null && studentList.size() > 0) {
            // jdk1.8实现list类型转换
            List<StudentBO> studentBOList =
                    studentList
                            .stream()
                            .map(s -> BeanMapper.map(s, StudentBO.class))
                            .collect(Collectors.toList());
            return studentBOList;
        }
        return null;
    }

    @Override
    public int addStudent(StudentBO studentBO) throws StudentException {
        baseParamCheck(studentBO);
        if (null != getStudentByNumber(studentBO.getStudentNumber())) {
            LogAndExceptionCommon.recordLogAndThrowExceptionByWarn(
                    ResponseCodeConstants.STUDENTNUMBER_IS_EXIST_CODE,
                    ResponseCodeConstants.STUDENTNUMBER_IS_EXIST_MSG,
                    "");
        }
        studentBO.setScore(80);
        studentBO.setPassword(studentBO.getStudentNumber().toString().substring(studentBO.getStudentNumber().toString().length() - 6));
        Student student = BeanMapper.map(studentBO, Student.class);
        return studentMapper.insert(student);
    }

    @Override
    public Map<String, Object> addStudentList(List<StudentBO> studentBOList) throws StudentException {
        Map<String, Object> map = new HashMap<String, Object>();
        List<Student> studentList = new ArrayList<Student>();
        List failList = new ArrayList(); //存脏数据数据
        int failResult = 0;
        List<Long> studentNumberList = studentMapper.findStudentNumberList();
        for (StudentBO studentBO : studentBOList) {

            String checkExcelParam = checkExcelParam(studentBO, studentNumberList);

            if ("验证通过!".equals(checkExcelParam)) {
                studentBO.setScore(80);
                studentBO.setPassword(studentBO.getStudentNumber().toString().substring(studentBO.getStudentNumber().toString().length() - 6));
                Student student = BeanMapper.map(studentBO, Student.class);
                studentList.add(student);
            } else {
                failResult++;
                StudentDTO studentDTO = BeanMapper.map(studentBO, StudentDTO.class);
                studentDTO.setFailReason(checkExcelParam);
                failList.add(studentDTO);

            }
        }
        map.put("failResult", failResult);
        map.put("failReason", failList);
        if (0 < studentList.size()) {
            // 限制每次执行条数
            int limitDataNumber = 200;
            int size = studentList.size();
            if (size < limitDataNumber) {
                studentMapper.addStudentList(studentList);
            } else {
                // 分批数
                int part = size / limitDataNumber;
                for (int i = 0; i < part; i++) {
                    List<Student> studentListPart =
                            studentList.subList(0, limitDataNumber);
                    studentMapper.addStudentList(studentListPart);
                    // 剔除
                    studentList.subList(0, limitDataNumber).clear();
                }
                if (!studentList.isEmpty()) {
                    // 存入剩下的
                    studentMapper.addStudentList(studentList);
                }
            }
        }
        return map;
    }


    @Override
    public int deleteStudentByStudentNumber(long studentNumber) throws StudentException {
        studentScoreService.deleteStudentScoreByNumber(tableNameDubboService.findByTableAndTime(
                Constants.STUDENT_SCORE_TABLE_NAME).getTableName(), studentNumber);
        return studentMapper.deleteStudentBySutdentNumber(studentNumber);
    }

    @Override
    public int deleteStudentByClassNumber(long classNumber) throws StudentException {
        return studentMapper.deleteStudentByClassNumber(classNumber);
    }

    @Override
    public int updateStudent(StudentBO studentBO) throws StudentException {
        Student student = BeanMapper.map(studentBO, Student.class);
        baseParamCheck(studentBO);
        return studentMapper.updateByStudentNumberSelective(student);
    }

    @Override
    public int updateScoreByStudentNumber(int score, long studentNumber) throws StudentException {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("score", score);
        map.put("studentNumber", studentNumber);
        return studentMapper.updateScoreByStudentNumber(map);
    }

    @Override
    public int updateScoreByStudentNumberBatch(List<StudentScoreBatchBO> studentScoreBatchBOList) throws StudentException {
        return studentMapper.updateScoreByStudentNumberBatch(studentScoreBatchBOList);
    }

    @Override
    public int updateStudentScoreTo80() throws StudentException {
        return studentMapper.updateStudentScoreTo80();
    }

    @Override
    public Map<String, Object> findHistoryScore(String studentScoreTable, long studentNumber) throws StudentException {
        Map<String, Object> map = new HashMap<String, Object>();
        int score = 80; //初始分数
        List<StudentScoreBO> studentScoreBOList = studentScoreService.findHistory(studentScoreTable, studentNumber);
        if (studentScoreBOList != null && studentScoreBOList.size() > 0) {
            for (StudentScoreBO studentScoreBO : studentScoreBOList) {
                score += studentScoreBO.getFinallyScore();  //累加
            }

        }
        map.put("score", score);
        map.put("historyScore", studentScoreBOList);
        return map;
    }

    @Override
    public Integer getCountByClassNumber(long classNumber) {
        return studentMapper.getCountByClassNumber(classNumber);
    }

    @Override
    public void logout(String token) {
        redisTemplate.delete(RedisConstants.STUDENT_LOGIN_USER_PREFIX + token);
    }

    @Override
    public void resetPassword(StudentBO student) throws StudentException {
        studentMapper.resetPassword(student.getStudentNumber(), student.getStudentNumber().toString().substring(student.getStudentNumber().toString().length() - 6));
    }


    /**
     * 检查参数
     *
     * @param studentBO
     * @return
     * @throws StudentException
     */
    private void baseParamCheck(StudentBO studentBO) throws StudentException {
        if (null == studentBO.getStudentNumber()) {
            LogAndExceptionCommon.recordLogAndThrowExceptionByWarn(
                    ResponseCodeConstants.USERNAME_IS_NOT_NULL_CODE,
                    ResponseCodeConstants.USERNAME_IS_NOT_NULL_MSG,
                    "");
        }
        if (null == studentBO.getClassNumber()) {
            LogAndExceptionCommon.recordLogAndThrowExceptionByWarn(
                    ResponseCodeConstants.CLASSNUMBER_IS_NOT_NULL_CODE,
                    ResponseCodeConstants.CLASSNUMBER_IS_NOT_NULL_MSG,
                    "");
        }
        if (null == studentBO.getName()) {
            LogAndExceptionCommon.recordLogAndThrowExceptionByWarn(
                    ResponseCodeConstants.STUDENTNAME_IS_NOT_NULL_CODE,
                    ResponseCodeConstants.STUDENTNAME_IS_NOT_NULL_MSG,
                    "");
        }
        if (null == studentBO.getDuty()) {
            LogAndExceptionCommon.recordLogAndThrowExceptionByWarn(
                    ResponseCodeConstants.DUTY_IS_NOT_NULL_CODE,
                    ResponseCodeConstants.DUTY_IS_NOT_NULL_MSG,
                    "");
        }
    }

    /**
     * 检查参数，excel
     *
     * @param studentBO
     * @param studentNumberList
     * @return
     * @throws StudentException
     */
    private String checkExcelParam(StudentBO studentBO, List<Long> studentNumberList) throws StudentException {
        if (null == studentBO.getStudentNumber() || "".equals(studentBO.getStudentNumber())) {
            return "学生学号不能为空！";
        }
        if (null == studentBO.getClassNumber() || "".equals(studentBO.getClassNumber())) {
            return "班级号码不能为空！";
        }
        if (null == studentBO.getName() || "".equals(studentBO.getName())) {
            return "学生姓名不能为空！";
        }
        if (null == studentBO.getDuty() || "".equals(studentBO.getClassNumber())) {
            return "学生职位不能为空！";
        }
        if (studentNumberList.contains(studentBO.getStudentNumber())) {
            return "学生学号不能重复！";
        }
        return "验证通过!";
    }
}
